/*
 * $Id: FileTransferTask.java,v 1.7 2009/06/09 15:46:19 navdeep_mahajan Exp $
 * 
 * Copyright (C) 2006 General Electric Company. All Rights Reserved.
 * 
 * This software is the confidential and proprietary information of the General
 * Electric Company (GE). You shall not disclose this software and shall use it
 * only in accordance with the terms of the license agreement you entered into
 * with GE.
 * 
 * GE MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
 * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
 * NON-INFRINGEMENT. GE SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
 * AS A RESULT OF USING, MODIFYING, OR DISTRIBUTING THIS SOFTWARE OR ITS
 * DERIVATIVES.
 */
package com.ge.healthcare.autosc.processor.dispatcher.tasks;

import java.io.File;
import java.net.UnknownHostException;
import java.security.NoSuchAlgorithmException;

import com.ge.healthcare.autosc.common.ASCUtil;
import com.ge.healthcare.autosc.common.commands.IFTCommand;
import com.ge.healthcare.autosc.common.database.pojo.ActTask;
import com.ge.healthcare.autosc.common.exceptions.BasicException;
import com.ge.healthcare.autosc.processor.exception.FileTransferException;

/**
 * @author 212042764
 * 
 */
public abstract class FileTransferTask extends BaseFileTransferTask {

	protected IFTCommand ftCommand = null;

	public void setUp(ActTask actTask) {
		super.setUp(actTask);
		this.setUpFTCommand();
		try {
			ftCommand.login(taskFtConnInfo.getHost(),
					taskFtConnInfo.getLogin(), taskFtConnInfo.getPassword());
		} catch (BasicException basicException) {
			throw new FileTransferException(
					"Failed to login to remote system using :" + taskFtConnInfo,
					basicException, PRC_FT_F_LOG_001);
		}
	}

	protected void complete() {
		try {
			if (!ASCUtil.isNullOrEmptyObject(ftCommand)) {
				ftCommand.logout();
			}
		} catch (BasicException basicException) {
			ftCommand = null;
		}
		super.complete();
	}

	protected abstract void setUpFTCommand();

	/**
	 * Returns the unique file name
	 * 
	 * @param destFile
	 * @return
	 * @throws FileTransferException
	 */
	protected String getInCompleteFile(String destFile, Long ftId) {
		try {
			return new StringBuffer().append(new File(destFile).getName())
					.append(".").append(ASCUtil.getUID(this)).append(
							INCOMPLETE_EXT).toString();
		} catch (NoSuchAlgorithmException noSuchAlgorithmException) {
			this
					.markFailed(
							ftId,
							destFile,
							new StringBuffer()
									.append(
											"Failed to created incomplete destination, missing alogorithm, file using:")
									.append(destFile).toString(),
							noSuchAlgorithmException);
		} catch (UnknownHostException unknownHostException) {
			this
					.markFailed(
							ftId,
							destFile,
							new StringBuffer()
									.append(
											"Failed to created incomplete destination, host unknown, file using:")
									.append(destFile).toString(),
							unknownHostException);
		}
		return null;
	}

	/**
	 * Method which returns the actual Destination Directory after parsing the
	 * DestDir Template.
	 * 
	 * @param destDir
	 * @param fTPCommand
	 * @throws FileTransferException
	 * @throws Exception
	 */
	private boolean traverseCurrDirectory(Long ftId, String destDir,
			String destFile) {
		boolean test = false;
		String transverseDir = "/";
		final String[] dirArray = destDir.split(transverseDir);
		if (dirArray == null || dirArray.length == 0) {
			this
					.markFailed(
							ftId,
							destFile,
							"Error retrieving the dirArray Array after Parsing through the Delimiter inside traverseCurrDirectory for FTP",
							null);
			return false;
		}
		try {
			for (int i = 0; i < dirArray.length; i++) {
				if (i == 0) {
					test = ftCommand.cd("/" + dirArray[i]);
				} else {
					test = ftCommand.cd(dirArray[i]);
				}
				if (!test) {
					if (i == 0) {
						ftCommand.cd("/");
					}
					ftCommand.mkdir(dirArray[i]);
					test = ftCommand.cd(dirArray[i]);
					if (!test) {
						this
								.markFailed(ftId, destFile, new StringBuffer()
										.append("Failed to cd to : ").append(
												dirArray[i]).append(
												" of Directory Path:").append(
												destDir).append(
												". Permission denied")
										.toString(), null);
						return false;
					}
				}
			}
		} catch (BasicException basicException) {
			this.markFailed(ftId, destFile, new StringBuffer().append(
					"Failed to transverse directory to:").append(destDir)
					.toString(), basicException);
			return false;
		}
		return true;
	}

	protected boolean validateTransferrable(File srcFile, File destFile,
			Long ftId) {
		if (!srcFile.exists()) {
			this.markFailed(ftId, destFile.getAbsolutePath(),
					"Src file not available for transfer:"
							+ srcFile.getAbsolutePath(), null);
			return false;
		}
		return true;
	}

	protected void putFile(File srcFile, String destFile,
			String incompleteDestFileName, Long ftId) {
		File destination = new File(destFile);
		String parentDir = destFile.substring(0, destFile
				.lastIndexOf(destination.getName()));
		// In case we can't transverse the directory we already have logged the
		// failure No need trying this further
		if (this.traverseCurrDirectory(ftId, parentDir, destFile)) {
			boolean successfullyPlaced = false;
			try {
				ftCommand.putFile(srcFile.getAbsolutePath(), new StringBuffer()
						.append(ftCommand.pwd()).append("//").append(
								incompleteDestFileName).toString());
				successfullyPlaced = true;
			} catch (BasicException basicException) {
				this.markFailed(ftId, destFile, new StringBuffer().append(
						"Failed to put src file:").append(
						srcFile.getAbsolutePath()).append(" as dest File:")
						.append(parentDir).append("/").append(
								incompleteDestFileName).toString(),
						basicException);
			}
			if (successfullyPlaced) {
				try {
					ftCommand.mv(incompleteDestFileName, destination.getName());
					this.markTaskFtStatusForSuccess(ftId);
					ftRecordDAO.saveSuccess(ftId, task.getTaskId(), destFile);
				} catch (BasicException basicException) {
					this.markFailed(ftId, destFile, new StringBuffer().append(
							"Failed to rename file:").append(
							incompleteDestFileName).append(" as dest File:")
							.append(destination.getName()).toString(),
							basicException);
				}
			}
		}
	}
}
